﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Configuration;
using System.Reflection;

namespace SvnNotes
{
    class Program
    {
        static void Main(string[] args)
        {
            new SvnNotesProgram(args).Run();
        }
    }

    public class SvnNotesProgram
    {
        private string[] _Args = null;
        public SvnNotesProgram(string[] args)
        {
            _Args = args;
        }

        public void Run()
        {
            if (_Args.Length == 0 || _Args[0] == "/help")
            {
                ShowHelp();
                return;
            }
            Stream stream = GetInputStream();
            IOutputTransformer transformer = GetOutputTransformer();
            SvnNotesFile.Create(stream, _Args[0], transformer, _Args);

        }

        public void ShowHelp()
        {
            Console.WriteLine("usage: svnnotes filename [options] [args]");
            Console.WriteLine();
            Console.WriteLine("/help:\t\tDisplays this help message");
            Console.WriteLine("/transformer:\tOptional, the output transformer to use");
            Console.WriteLine("\t\tin the format \"fulltypename, assemblyfilename\"");
            Console.WriteLine("/input:\t\tOptional, If your not piping the svn output");
            Console.WriteLine("\t\tuse this to specify an svn log file");
            Console.WriteLine();
            Console.WriteLine("examples:");
            Console.WriteLine("svn log --xml --revision 4365:HEAD | svnnotes log.txt");
            Console.WriteLine("svn log --xml --revision 4365:HEAD | svnnotes log.txt /transformer \"Foo.Bar.MyTranformer, Foo.Bar.dll\"");
            Console.WriteLine("svnnotes log.txt /input \"svnlogfile.xml\"");
        }

        private IOutputTransformer GetOutputTransformer()
        {
            IOutputTransformer outputTranformer = null;
            CommandLineOption transformerArg = CommandLineOption.GetOption("/transformer");
            if (transformerArg != null)
            {
                if (String.IsNullOrEmpty(transformerArg.Value))
                {
                    throw new InvalidProgramException("/transformer has no value");
                }

                Regex r = new Regex(@"^(?<type>\S+)(\s+)?,(\s+)?(?<assemblyfile>.*)$");
                Match m = r.Match(transformerArg.Value);
                if (m.Success)
                {
                    outputTranformer = OutputTransformerFactory.GetOutputTransformer(m.Groups["assemblyfile"].Value, m.Groups["type"].Value);
                }
                else
                {
                    throw new InvalidProgramException("Invalid value for option /transformer, format should be:- \"Path.To.Type, AssemblyName.dll\"");
                }
            }

            return outputTranformer;
        }

        private Stream GetInputStream()
        {
            Stream stream = null;

            CommandLineOption input = CommandLineOption.GetOption("/input");
            if (input != null)
            {
                if (String.IsNullOrEmpty(input.Value))
                    throw new InvalidProgramException("/input has no value");

                stream = File.OpenRead(input.Value);
            }
            else
            {
                stream = Console.OpenStandardInput();
            }

            return stream;
        }
    }
}
